package cn.micai.base.lambda;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 描述：Java 8 – Stream Collectors groupingBy examples
 * <p>
 *
 * @author: 赵新国
 * @date: 2018/6/21 16:42
 */
public class StreamsCollectorsGroupingByExample {

    public static void main(String [] args) {

        /*// Group By, Count and Sort

        // Group by a List and display the total count of it.

        // 3 apple, 2 banana, others 1
        List<String> items = Arrays.asList("apple","apple","banana","apple","banana","orange","banana","papaya");

        Map<String, Long> result =
            items.stream().collect(
                Collectors.groupingBy(
                    Function.identity(), Collectors.counting()
                )
            );

        System.out.println(result);

        Map<String, Long> finalMap = new HashMap<>();

        // Sort a map and add to finalMap
        result.entrySet().stream()
                .sorted(Map.Entry.<String, Long>comparingByValue()
                        .reversed()).forEachOrdered(e->finalMap.put(e.getKey(),e.getValue()));
        System.out.println(finalMap);*/

        // List Objects
        // Examples to ‘group by’ a list of user defined Objects.

        // 3 apple, 2 banana, others 1
        List<Item> items = Arrays.asList(
                new Item("apple", 10, new BigDecimal("9.99")),
                new Item("banana", 20, new BigDecimal("19.99")),
                new Item("orang", 10, new BigDecimal("29.99")),
                new Item("watermelon", 10, new BigDecimal("29.99")),
                new Item("papaya", 20, new BigDecimal("9.99")),
                new Item("apple", 10, new BigDecimal("9.99")),
                new Item("banana", 10, new BigDecimal("19.99")),
                new Item("apple", 20, new BigDecimal("9.99"))
        );

        //Group by + Count
        Map<String, Long> counting = items.stream().collect(
                Collectors.groupingBy(Item::getName, Collectors.counting()));

        System.out.println(counting);

        //Group by + Sum qty
        Map<String, Integer> sum = items.stream().collect(
                Collectors.groupingBy(Item::getName, Collectors.summingInt(Item::getQty)));
        System.out.println(sum);

        //Group by price
        Map<BigDecimal, List<Item>> price = items.stream().collect(
                Collectors.groupingBy(Item::getPrice));
        System.out.println(price);

        //Group by price, uses 'mapping' to convert List<Item> to Set<String>
        //group by + mapping to Set
        Map<BigDecimal, Set<String>> result =
                items.stream().collect(
                        Collectors.groupingBy(Item::getPrice,
                                Collectors.mapping(Item::getName, Collectors.toSet())
                        )
                );
        System.out.println(result);

    }

}
